#include <iostream>

using namespace std;

void test_prim() {
    int points, edges, min;
    int infinity = 99999999;
    cin >> points >> edges;

    int edge[7][7];
    int dis[7];
    int flag[7] = {0};

    // 初始化 edge 矩阵
    for (int i = 1; i <= points; i++) {
        for (int j = 1; j <= points; j++) {
            edge[i][j] = (i == j) ? 0 : infinity;
        }
    }

    // 将用户输入的边填入 edge 矩阵
    int p1, p2, w;
    for (int i = 1; i <= edges; i++) {
        cin >> p1 >> p2 >> w;
        edge[p1][p2] = w;
        edge[p2][p1] = w;
    }

    // 初始化1号顶点到其它顶点的距离
    for (int i = 1; i <= points; i++) {
        dis[i] = edge[1][i];
    }
    flag[1] = 1;    // 标记 1 号顶点已处理过

    int count = 1;
    int j = 0;
    int sum = 0;
    while (count < points) {
        min = infinity;
        for (int i = 1; i <= points; i++) {

            // 每次选择1号顶点到其它顶点的最短距离加入生成树
            if (flag[i] == 0 && dis[i] < min) {
                min = dis[i];
                j = i;
            }
        }
        /* 循环结束后，1 号顶点距离 j 号顶点最近，距离为 dis[j] */

        flag[j] = 1;
        count++;
        sum += dis[j];

        // 选择出的顶点再延伸更新1号顶点到其它顶点的距离
        // 1 号顶点和 j 号顶点组成了最小生成树，被当作一个整体。j 是这颗树的末端。计算这棵树（即从 j 出发，到周边（未访问）的节点的最小距离。
        for (int i = 1; i <= points; i++) {
            if (flag[i] == 0 && dis[i] > edge[j][i]) {
                dis[i] = edge[j][i]; // 如果满足条件则更新
            }
        }
    }

    cout << sum << endl;

}

int main() {
    test_prim();
}